package view;

import java.io.*;
import java.util.Scanner;
import utilityClasses.FileOutput;
import utilityClasses.Timer;

import controller.Controller;


/**
 * BenchMarkView is a view used to benchmark load of data and search execution time. 
 * The view generates an output file with comma-separated values to be loaded into 
 * a spreadsheet for statistical analysis.  
 * 
 */
public class BenchMarkView implements IView {
	private Controller controller;
	private String input = "";
	private String sample[];
	String throwAwayArray[];
	//private int sampleSize = 100;
	private int totalURLS = 0;
	public FileOutput outputLog;
	Scanner inputLine;

	/**
	 * Constructor creating and running the benchmark view. Outputs a menu where users can choose 
	 * between running data load test or search execution test. Outputs to a file in the output-folder.
	 * @param c reference to the controller
	 */
	public BenchMarkView(Controller c) {
	
		outputLog = new FileOutput("output/output-" + (int) (System.currentTimeMillis()/1000) + ".txt");
		setController(c);
		c.setView(this);
		
		System.out.println("A very cool (text-based) search engine!");
		outputLog.println("A very cool (text-based) search engine!");
		System.out.println("Automated Benchmarking test.");
		outputLog.println("Automated Benchmarking test.");
		System.out.println(c.toString());
		outputLog.println(c.toString());
		System.out.println();
	
		//menu for selecting tests
		System.out.println("What test do you want to run?");
		System.out.println("1. Load test");
		System.out.println("2. Search test");
		System.out.print("Input: ");
		inputLine = new Scanner(new InputStreamReader(System.in));
		int testType = inputLine.nextInt();
		if (testType <= 0 || testType > 2) System.exit(-1);
		
		
		//load either load or search test
		switch (testType) {
		case 1:	runLoadTest();
				break;
		case 2: runSearchTest();
				break;
		default:System.out.println("Not valid input. Exiting");  
				System.exit(1);		
		}
		
		outputLog.flush();
			
	}

	@Override
	public void doSearch() {
		controller.doSearch(input);
	}

	@Override
	public void setController(Controller ctrl) {
		controller = ctrl;
	}

	@Override
	public void showResult(String[] result) {		
		if (result != null) {
			totalURLS += result.length;
		} 
		
	}
	

	private void loadSample(int sampleSize) {
		sample = controller.getSample(sampleSize);
	}

/**
 * Method used to run the search execution benchmark
 */
	private void runSearchTest() {
		long totalTime=0;
		final String[] ops = {" AND ", " OR "};
		//get user input
		System.out.print("Enter sample size: ");
		int sampleSize = inputLine.nextInt();
		if (sampleSize <= 0) System.exit(-1);
		System.out.print("Enter number of trials: ");
		int trials = inputLine.nextInt();
		if (trials <= 0) System.exit(-1);
		System.out.println("Starting test.");
		for  (int i = 0; i < trials; i++) {
			outputLog.print(""+i);
			loadSample(sampleSize);
			long start = Timer.startTime();
			for (int j = 0; j < sample.length; j++) {
				if (controller.isBooleanSearch()) input = sample[j] + ops[(int) Math.round(Math.random())] + ((j+1 < sample.length) ? sample[j+1] : sample[0]);
				
				else input = sample[j];
				doSearch();
			}
			long time = Timer.getTime(start);
			totalTime += time;
			outputLog.println("," + time);

	}
		System.out.println(totalTime + "ms total time.");
		System.out.println("Done.");
	}

	@Override
	public String toString() {
		return this.getClass().getName();
	}
	/**
	 * Method used to run the load test.
	 */
	private void runLoadTest() {
		long totalTime=0;
		String[] filename= null;
		//get user input
		
		System.out.println("1. small file");
		System.out.println("2. medium file");
		System.out.println("3. big file");
		System.out.println("4. all files");
		System.out.println("Select input data file:");
		int file = inputLine.nextInt();
		
		switch(file) {
		case 1:	filename = new String[1];
				filename[0] = "data/itcwww-small.txt";
				break;
		case 2:	filename = new String[1];
				filename[0] = "data/itcwww-medium.txt";
				break;

		case 3:	filename = new String[1];
				filename[0] = "data/itcwww-big.txt";
				break;

		case 4:	filename = new String[3];
				filename[0] = "data/itcwww-small.txt";
				filename[1] = "data/itcwww-medium.txt";
				filename[2] = "data/itcwww-big.txt";
				break;
		default:System.out.println("Wrong input. Exiting.");
				System.exit(-1);
		}
		
		System.out.print("Enter number of trials: ");
		int trials = inputLine.nextInt();
		if (trials <= 0) System.exit(-1);
		System.out.println("Starting test.");
		for (int i = 0; i < filename.length; i++) {
			System.out.println("Filename: " + filename[i]);
			outputLog.println("Filename: " + filename[i]);
			for  (int j = 0; j < trials; j++) {
				long time = controller.reLoadData(filename[i]);
				totalTime += time;
				System.out.println("" +j  + ", " + time);
				outputLog.println("" +j  + ", " + time);
				}
		outputLog.println(totalTime + "ms total time for " + filename[i]);
		}
		System.out.println("Done.");
	}
}

